package com.ying.controller.system;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.anji.captcha.model.common.ResponseModel;
import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.ying.core.exception.CustomException;
import com.ying.core.form.LoginForm;
import com.ying.core.response.ApiResponse;
import com.ying.core.response.ResultCode;
import com.ying.po.system.User;
import com.ying.service.system.UserService;
import io.swagger.annotations.Api;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.request.AuthGiteeRequest;
import me.zhyd.oauth.request.AuthGithubRequest;
import me.zhyd.oauth.request.AuthOschinaRequest;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/user")
@Api(tags = "Login接口")
public class LoginController {

    @Autowired
    private UserService userService;

    @Autowired
    private CaptchaService captchaService;

    @Value("${justauth.type.GITEE.client-id}")
    private String GiteeClientId;

    @Value("${justauth.type.GITEE.client-secret}")
    private String GiteeClientSecret;

    @Value("${justauth.type.GITEE.redirect-uri}")
    private String GiteeRedirectUri;

    @Value("${justauth.type.OSCHINA.client-id}")
    private String OSCHINAClientId;

    @Value("${justauth.type.OSCHINA.client-secret}")
    private String OSCHINAClientSecret;

    @Value("${justauth.type.OSCHINA.redirect-uri}")
    private String OSCHINARedirectUri;

    @Value("${justauth.type.GITHUB.client-id}")
    private String GITHUBClientId;

    @Value("${justauth.type.GITHUB.client-secret}")
    private String GITHUBClientSecret;

    @Value("${justauth.type.GITHUB.redirect-uri}")
    private String GITHUBRedirectUri;


    @PostMapping("/login")
    public ApiResponse login(@RequestBody LoginForm loginForm) {

        String username = loginForm.getUsername();
        String password = loginForm.getPassword();
        User user = userService.findByUsernameAndPassword(username, password);
        if (user == null) {
            return ApiResponse.failure(ResultCode.USER_LOGIN_ERROR);
        }
        StpUtil.login(user.getId());
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        String tokenValue = tokenInfo.getTokenValue();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("token", tokenValue);
        return ApiResponse.success(map);
    }

    @GetMapping("/info")
    public ApiResponse info(@RequestParam("token") String token) {
        if (!StpUtil.isLogin()) {
            return ApiResponse.failure(ResultCode.USER_NOT_LOGGED_IN);
        }
        Integer id = StpUtil.getLoginIdAsInt();
        if (StpUtil.getTokenInfo().tokenValue.equals(token)) {
            User user = userService.findById(id);
            return ApiResponse.success(user);
        } else {
            return ApiResponse.failure(ResultCode.PARAM_IS_INVALID);
        }

    }

    @GetMapping("/logout")
    public ApiResponse logout() {
        if (!StpUtil.isLogin()) {
            return ApiResponse.failure(ResultCode.USER_NOT_LOGGED_IN);
        }
        StpUtil.logout();
        return ApiResponse.success();
    }

    @PostMapping("/captcha-check")
    public ApiResponse captchaCheck(@RequestBody CaptchaVO captchaVO) {
        // 验证码
        ResponseModel response = captchaService.verification(captchaVO);
        if(!response.isSuccess()) {
//            验证码校验失败，返回信息告诉前端
//            repCode  0000  无异常，代表成功
//            repCode  9999  服务器内部异常
//            repCode  0011  参数不能为空
//            repCode  6110  验证码已失效，请重新获取
//            repCode  6111  验证失败
//            repCode  6112  获取验证码失败,请联系管理员
//            repCode  6113  底图未初始化成功，请检查路径
//            repCode  6201  get接口请求次数超限，请稍后再试!
//            repCode  6206  无效请求，请重新获取验证码
//            repCode  6202  接口验证失败数过多，请稍后再试
//            repCode  6204  check接口请求次数超限，请稍后再试!
            throw new CustomException(ResultCode.VERTICAL_ERROR, "LoginController.login");
        }
        return ApiResponse.success();
    }

    // 第三方登录
    @GetMapping("/oauth/render/{type}")
    public void thirdLogin(@PathVariable String type, HttpServletResponse response) throws IOException {
        AuthRequest authRequest = this.getAuthRequest(type);
        if (authRequest == null) {
            throw new CustomException(ResultCode.THIRD_LOGIN_ERROR, "LoginController.thirdLogin");
        }
        response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
    }

    @RequestMapping("/oauth/{type}/callback")
    public ApiResponse thirdDoLogin(@PathVariable String type,
                               AuthCallback callback, HttpServletResponse response) throws IOException {
        AuthRequest authRequest = getAuthRequest(type);
        if (authRequest == null) {
            return ApiResponse.failure(ResultCode.THIRD_LOGIN_ERROR);
        }
        // 得到user信息
        User user = userService.getUserInfoFormAuthRes(authRequest.login(callback));
        // 查找是否有该user，没有就在数据库里生成一个
        Integer userId = userService.findByUserObj(user);
        if (userId == null) {
            userId = userService.create(user);
        }
        // 给该用户设置权限
        //……

        // login,返回token给前端
        StpUtil.login(userId);
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        String tokenValue = tokenInfo.getTokenValue();
        Map<String, Object> map = new HashMap<String, Object>();
//        map.put("token", tokenValue);
        map.put("userId", userId);

        return ApiResponse.success();
    }

    private AuthRequest getAuthRequest(String type) {
        if (type.equalsIgnoreCase("gitee")) {
            return new AuthGiteeRequest(AuthConfig.builder()
                    .clientId(GiteeClientId)
                    .clientSecret(GiteeClientSecret)
                    .redirectUri(GiteeRedirectUri)
                    .build());
        } else if (type.equalsIgnoreCase("oschina")) {
            return new AuthOschinaRequest(AuthConfig.builder()
                    .clientId(OSCHINAClientId)
                    .clientSecret(OSCHINAClientSecret)
                    .redirectUri(OSCHINARedirectUri)
                    .build());
        } else if (type.equalsIgnoreCase("github")) {
            return new AuthGithubRequest(AuthConfig.builder()
                    .clientId(GITHUBClientId)
                    .clientSecret(GITHUBClientSecret)
                    .redirectUri(GITHUBRedirectUri)
                    .build());
        }
        return null;
    }


}
